// ------------------------------------------------------------------------------------------
// Licensed by Interprise Solutions.
// http://www.InterpriseSolutions.com
// For details on this license please visit  the product homepage at the URL above.
// THE ABOVE NOTICE MUST REMAIN INTACT.
// ------------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;

namespace InterpriseSuiteEcommerceControls
{
    public enum NavigationRenderOption
    {
        Link,
        Button
    }

    public enum NavigationLayout
    {
        Vertical,
        Horizontal
    }

    [ToolboxData("<{0}:NavigationControl runat=server></{0}:NavigationControl>"), 
     DefaultEvent("LinkClicked")]
    public class NavigationControl : CompositeControl
    {        
        #region Variable Declaration
        
        private readonly string[] _letters = { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" };
        private const string HTML_SPACE = "&nbsp;";
        private const string HTML_NEW_LINE = "</BR>";
        private string _filter = string.Empty;
        private const string APPEARANCE_CATEGORY = "Appearance";
        private const string DEFAULT_ALL_TEXT = "All";
        private const string DEFAULT_NUMBER_TEXT = "#";
        
        #endregion

        #region Custom Events

        public event EventHandler<LinkClickedEventArgs> LinkClicked;

        #endregion

        public NavigationControl(){}

        #region Properties

        /// <summary>
        /// Groups
        /// </summary>
        [Browsable(true), Category(APPEARANCE_CATEGORY)]
        public int Groups
        {
            get 
            {
                if (ViewState["Groups"] == null) { return 1; }
                return (int)ViewState["Groups"];
            }
            set 
            {
                ViewState["Groups"] = value;
                ChildControlsCreated = false;
            }
        }

        /// <summary>
        /// Navigation position
        /// </summary>
        [Browsable(true), Category(APPEARANCE_CATEGORY)]
        public NavigationLayout NavigationLayout
        {
            get
            {
                if (ViewState["NavigationLayout"] == null) { return NavigationLayout.Horizontal; }
                return (NavigationLayout)ViewState["NavigationLayout"];
            }
            set
            {
                ViewState["NavigationLayout"] = value;
                ChildControlsCreated = false;
            }
        }

        /// <summary>
        /// Gets or sets what control will render as navigation links
        /// </summary>
        [Browsable(true), Category(APPEARANCE_CATEGORY)]
        public NavigationRenderOption NavigationRender
        {
            get 
            {
                if (ViewState["NavigationRender"] == null) { return NavigationRenderOption.Link; }
                return (NavigationRenderOption)ViewState["NavigationRender"];
            }
            set 
            {
                ViewState["NavigationRender"] = value;                
                ChildControlsCreated = false;
            }
        }

        #endregion

        #region ShowAll        
        /// <summary>
        /// Gets or sets whethere to display the All text link besides the letters
        /// </summary>
        [Browsable(true), Category(APPEARANCE_CATEGORY)]
        public bool ShowAll
        {
            get
            {
                if (ViewState["ShowAll"] == null) { return false; }
                return (bool)ViewState["ShowAll"];
            }
            set
            {
                ViewState["ShowAll"] = value;
            }
        }
        #endregion


        #region ShowAllText        
        /// <summary>
        /// Gets or sets the text to display when the show "all" is enabled
        /// </summary>
        [Browsable(true), Category(APPEARANCE_CATEGORY)]
        public string ShowAllText
        {
            get
            {
                if (ViewState["ShowAllText"] == null) { return DEFAULT_ALL_TEXT; }
                return (string)ViewState["ShowAllText"];
            }
            set
            {
                ViewState["ShowAllText"] = value;
            }
        }
        #endregion

        #region ShowNumber
        /// <summary>
        /// Gets or sets whether to display the number in the links besides the letters
        /// </summary>
        [Browsable(true), Category(APPEARANCE_CATEGORY)]
        public bool ShowNumber
        {
            get
            {
                if (ViewState["ShowNumber"] == null) { return false; }
                return (bool)ViewState["ShowNumber"];
            }
            set
            {
                ViewState["ShowNumber"] = value;
            }
        }
        #endregion

        #region ShowNumberText
        /// <summary>
        /// Gets or sets the text to display for the number link
        /// </summary>
        [Browsable(true), Category(APPEARANCE_CATEGORY)]
        public string ShowNumberText
        {
            get
            {
                if (ViewState["ShowNumberText"] == null) { return DEFAULT_NUMBER_TEXT; }
                return (string)ViewState["ShowNumberText"];
            }
            set
            {
                ViewState["ShowNumberText"] = value;
            }
        }
        #endregion


        #region Methods

        #region CreateChildControls
        /// <summary>
        /// Create the child controls
        /// </summary>
        protected override void CreateChildControls()
        {
            Panel div = new Panel();

            int split = this.Groups- 1;
            if (split > _letters.Length || split <= 0) { split = 1; }

            string separator = string.Empty;
            switch(this.NavigationLayout)
            {
                case NavigationLayout.Horizontal:
                    separator =  HTML_SPACE;                        
                    break;
                case NavigationLayout.Vertical:
                    separator = HTML_NEW_LINE;
                    break;
            }

            if (this.ShowAll)
            {
                AddLink(div, this.ShowAllText);
                // add separator
                div.Controls.Add(new LiteralControl(separator));
            }

            if (this.ShowNumber)
            {
                AddLink(div, this.ShowNumberText);
                // add separator
                div.Controls.Add(new LiteralControl(separator));
            }

            for (int ctr = 0; ctr < _letters.Length; ctr += (split > 1 || this.Groups == 2) ? (split + 1) : split)
            {
                int last = (ctr + split) < _letters.Length ? ctr + split : _letters.Length - 1;
                string caption = (split > 1 || this.Groups == 2) && ctr != last ? string.Format("{0}-{1}", _letters[ctr], _letters[last]) : _letters[ctr];
                AddLink(div, caption);
                div.Controls.Add(new LiteralControl(separator));
            }

            Controls.Add(div);
        }
        #endregion

        #region AddLink
        /// <summary>
        /// Adds a link to the site
        /// </summary>
        /// <param name="container">The container</param>
        /// <param name="caption">The text</param>
        /// <returns></returns>
        private IButtonControl AddLink(Control container, string caption)
        {
            IButtonControl linkControl = null;
            switch (this.NavigationRender)
            {
                case NavigationRenderOption.Link:
                    linkControl = new LinkButton();                    
                    break;
                case NavigationRenderOption.Button:
                    linkControl = new Button();
                    break;
            }
            linkControl.Text = caption;
            linkControl.Click += Link_Clicked;
            container.Controls.Add(linkControl as Control);
            return linkControl;
        }
        #endregion

        #endregion

        #region OnLoad
        /// <summary>
        /// Override on load
        /// </summary>
        /// <param name="e"></param>
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
        }
        #endregion

        #region OnLinkClicked
        /// <summary>
        /// OnLinkClicked
        /// </summary>
        /// <param name="e"></param>
        protected virtual void OnLinkClicked(LinkClickedEventArgs e)
        {
            if (LinkClicked != null)
            {
                LinkClicked(this, e);
            }
        }
        #endregion        

        #region SaveViewState
        /// <summary>
        /// Save view state info
        /// </summary>
        /// <returns></returns>
        protected override object SaveViewState()
        {
            return base.SaveViewState();
        }
        #endregion

        #region LoadViewState
        /// <summary>
        /// Load the viewstate info
        /// </summary>
        /// <param name="savedState"></param>
        protected override void LoadViewState(object savedState)
        {
            base.LoadViewState(savedState);
        }

        #endregion

        #region Event Handlers

        #region Link_Clicked
        /// <summary>
        /// Link Click event handler
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Link_Clicked(object sender, EventArgs e)
        {
            OnLinkClicked(new LinkClickedEventArgs((sender as IButtonControl).Text, this.ShowAll, this.ShowNumber));
        }
        #endregion        

        #endregion
    }

    public class LinkClickedEventArgs : EventArgs
    {
        #region Variable Declaration
        private string _text = string.Empty;
        private bool _showAll = false;
        private bool _showNumber = false;
        #endregion

        #region Constructor

        /// <summary>
        /// LinkClickedEventArgs
        /// </summary>
        /// <param name="text"></param>
        public LinkClickedEventArgs(string text)
        {
            _text = text;
        }

        /// <summary>
        /// LinkClickedEventArgs
        /// </summary>
        /// <param name="text"></param>
        /// <param name="showAll"></param>
        /// <param name="showNumber"></param>
        public LinkClickedEventArgs(string text, bool showAll, bool showNumber) : this(text)
        {
            _showAll = showAll;
            _showNumber = showNumber;
        }
        #endregion

        #region Properties        

        #region Text
        /// <summary>
        /// Gets the text display filter
        /// </summary>
        public string Text
        {
            get { return _text; }
        }
        #endregion

        #region ShowAll
        /// <summary>
        /// Gets whether to show the result set without filtering
        /// </summary>
        public bool ShowAll
        {
            get { return _showAll; }
        }
        #endregion

        #region ShowNumber       
        /// <summary>
        /// Gets whether the number filter was shown
        /// </summary>
        public bool ShowNumber
        {
            get { return _showNumber; }
        }
        #endregion

        #endregion
    }

}
